# Copyright (c) 2022, Frappe and contributors
# For license information, please see license.txt

import frappe
from frappe.model.document import Document

from press.runner import Ansible
from press.utils import log_error


class MalwareScan(Document):
	def after_insert(self):
		self.check_clamav()

	def check_clamav(self):
		self.status = "Pending"
		self.save()
		frappe.db.commit()
		frappe.enqueue_doc(self.doctype, self.name, "_check_clamav", queue="default")

	def _check_clamav(self):
		try:
			ansible = Ansible(
				playbook="pkg_exists.yml",
				server=frappe.get_doc(self.server_type, self.server),
				variables={"pkg": "clamav"},
			)
			self.reload()
			self.play = ansible.play
			self.status = "Running"
			self.save()
			frappe.db.commit()
			play = ansible.run()
			if play.status == "Success":
				self.status = "Installed"
			else:
				self.status = "Not Installed"
		except Exception:
			log_error("ClamAV Install Exception", scan=self.as_dict())
			self.status = "Failure"
		self.save()

	@frappe.whitelist()
	def start(self):
		self.status = "Pending"
		self.save()
		frappe.db.commit()
		frappe.enqueue_doc(self.doctype, self.name, "_start", queue="long", timeout=32000)

	def _start(self):
		try:
			ansible = Ansible(
				playbook="malware_scan.yml",
				server=frappe.get_doc(self.server_type, self.server),
			)
			self.reload()
			self.play = ansible.play
			self.status = "Running"
			self.save()
			frappe.db.commit()
			play = ansible.run()
			if play.status == "Success":
				self.succeed()
			else:
				self.fail()
		except Exception:
			log_error("Malware Scan Exception", scan=self.as_dict())
			self.fail()
		self.save()

	def succeed(self):
		output = frappe.db.get_value(
			"Ansible Task", {"task": "Scan home directory", "play": self.play}, "output"
		)
		if "Infected files:" in output:
			if "Infected files: 0" in output:
				self.status = "Clean"
			else:
				self.status = "Infected"
				self.send_infected_alert()
			return
		self.fail()

	def send_infected_alert(self):
		domain = frappe.get_value("Press Settings", "Press Settings", "domain")
		message = f"""
Malware Scan for *{self.server}* found malware, review.

[Malware Scan]({domain}{self.get_url()})
"""
		self.send_alert(message)

	def fail(self):
		self.status = "Failure"
		domain = frappe.get_value("Press Settings", "Press Settings", "domain")
		message = f"""
Malware Scan for *{self.server}* failed.

[Malware Scan]({domain}{self.get_url()})
"""
		self.send_alert(message)

	def send_alert(self, message):
		# chat_id = frappe.db.get_value(
		# 	"Press Settings", "Press Settings", "telegram_alert_chat_id"
		# )
		# telegram = Telegram(chat_id)
		# telegram.send(message)
		pass
